/**
 *  Copyright (c)  2011-2020 Panguso, Inc.
 *  All rights reserved.
 *
 *  This software is the confidential and proprietary information of Panguso, 
 *  Inc. ("Confidential Information"). You shall not
 *  disclose such Confidential Information and shall use it only in
 *  accordance with the terms of the license agreement you entered into with Panguso.
 */
package cn.edu.thu.log.web.service.impl;

import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.deckfour.xes.model.XLog;
import org.deckfour.xes.model.XTrace;

import cn.edu.thu.log.web.service.WebConfigReadService;
import cn.edu.thu.log.web.service.XESConvertService;
import cn.edu.thu.log.xes.XESConvertormodified;
import cn.edu.thu.log.xes.XESConvertorMonitor;
import cn.edu.thu.log.xes.XESMerge;
import cn.edu.thu.log.xes.XESReader;

/**
 * implementation of service XES Convert.
 * 
 * @author meng
 * 
 */
public class XESConvertServiceImp implements XESConvertService {

	private XLog xlog;
	private String readFilePath;
	private static XESConvertService  instance;
	private String resultFile;
	/**
	 * @return the writer
	 */
	public XESConvertormodified getWriter() {
		return writer;
	}
	/**
	 * @param writer the writer to set
	 */
	public void setWriter(XESConvertormodified writer) {
		this.writer = writer;
	}
	/**
	 * @return the instancepool
	 */
	public static HashMap<String, XESConvertService> getInstancepool() {
		return instancepool;
	}
	/**
	 * @param instancepool the instancepool to set
	 */
	public static void setInstancepool(HashMap<String, XESConvertService> instancepool) {
		XESConvertServiceImp.instancepool = instancepool;
	}
	/**
	 * @param xlog the xlog to set
	 */
	public void setXlog(XLog xlog) {
		this.xlog = xlog;
	}

	private String classify;
	private String sessionID;
	

	/**
	 * 
	 * @return
	 * @author fenyo rome
	 * @date 2013-4-26
	 */
	public String getSessionID() {
		return sessionID;
	}
	
	/**
	 * 
	 * @param sessionID
	 * sessionID
	 * @author fenyo rome
	 * @date 2013-4-26
	 */
	public void setSessionID(String sessionID) {
		this.sessionID = sessionID;
	}

	private XESConvertormodified writer;
	/**
	 * 
	 */
	public String getReadFilePath() {
		return readFilePath;
	}	
	/**
	 * @param readFilePath
	 * resultFile
	 */
	public void setReadFilePath(String readFilePath) {
		this.readFilePath = readFilePath;
	}
	/**
	 * 
	 */
	public String getResultFile() {
		return resultFile;
	}
	/**
	 * @param resultFile
	 * resultFile
	 */
	public void setResultFile(String resultFile) {
		this.resultFile = resultFile;
	}
	/**
	 * HashMap
	 */
	private static HashMap<String, XESConvertService> instancepool = null;
	/**
	 * instancepool
	 */
	static {
		instancepool = new HashMap<String, XESConvertService>();
	}
	/**
	 * 
	 * @param sessionID
	 * sessionID
	 * @return
	 * @author fenyo rome
	 * @date 2013-4-26
	 */
	public static synchronized  XESConvertService instance() {
		if (instance == null ) {
			instance = new XESConvertServiceImp();
		}
		return instance;
	}
	/**
	 * 
	 * @param sessionID
	 * sessionID
	 * @author fenyo rome
	 * @date 2013-4-26
	 */
	public static synchronized  void signoff(String sessionID) {
		if (instancepool.get(sessionID) != null) {
			instancepool.remove(sessionID);
		}
	}
	
	private XESConvertServiceImp() {
	}
	/**
	 * 
	 */
	public void convert() {
		if (readFilePath == null) {
			System.out.print("\nchoose log file");
		} else if (resultFile == null) {
			System.out.print("\ngive the name of resultFile");
		} else {
			WebConfigReadService configRead = WebConfigReadServiceImpl
					.instance();
			writer = new XESConvertormodified(configRead, readFilePath, classify);
			try {
				writer.write(resultFile);
			} catch (Exception ex) {
				Logger.getLogger(XESConvertServiceImp.class.getName()).log(
						Level.SEVERE, null, ex);
			}
			xlog = writer.getLog();
		}
	}
	/**
	 * 
	 */
	public XLog getXlog() {

		return xlog;
	}
	/**
	 * @param standardLogFile
	 *            the classify to set
	 */
	public Collection<XLog> readStandardLog(String standardLogFile) {
		XESReader xesReader = new XESReader();
		Collection<XLog> logs;
		logs = xesReader.readStandardLog(standardLogFile);
		return logs;
	}
	/**
	 * 
	 */
	public Collection<XLog> readStandardLog() {
		XESReader xesReader = new XESReader();
		Collection<XLog> logs;
		logs = xesReader.readStandardLog();
		return logs;
	}
	/**
	 * @param sourcePath
	 *            the classify to set
	 * @param name
	 *            the classify to set
	 */
	public XLog mergeXESToLog(String sourcePath, String name) {
		// System.out.print("\nget into merge service");
		XESMerge xesMerge = new XESMerge();
		xlog = xesMerge.mergeXES(sourcePath, name);
		return xlog;
	}
	/**
	 * 
	 */
	public String getAnalysisResult() {
		int totalEvent = writer.getTotalEvent();
		Hashtable<String, Integer> caseBranchMap = writer.getCaseBranchMap();
		Hashtable<XTrace, String> lastestArrivalMap = XESConvertorMonitor
				.instance().getLastestArrivalMap();
		String analysisResult = "";
		analysisResult = analysisResult + "the number of events:";
		Enumeration<String> caseBranchInteror = caseBranchMap.keys();
		int traceNum = 0;

		while (caseBranchInteror.hasMoreElements()) {
			String traceInfo = "";
			String caseBranch = caseBranchInteror.nextElement();
			traceInfo = traceInfo + "trace name:" + caseBranch + " ";
			traceNum++;
		}
		analysisResult = analysisResult + "the number of traces:";
		analysisResult = analysisResult + traceNum + "\n";
		// System.out.println("\nanalysisResult:" + analysisResult);
		return analysisResult;

	}

	/**
	 * @return the classify
	 */
	public String getClassify() {
		return classify;
	}

	/**
	 * @param classify
	 *            the classify to set
	 */
	public void setClassify(String classify) {
		this.classify = classify;
	}
}
